feat(sdk): add AxonListParams support and auto-pagination to AxonOps.list()#763
Conversation
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
AxonListParams support and auto-pagination to AxonOps.list()
AxonListParams support and auto-pagination to AxonOps.list()AxonListParams support and auto-pagination to AxonOps.list()
| const secretValue = 'test-value-from-gateway'; | ||
|
|
||
| expect(createResult.httpCode).toBe(200); | ||
| const created = JSON.parse(createResult.responseBody); | ||
| expect(created.name).toBe(secretName); | ||
| const createResult = await curlRequest('POST', '/v1/secrets', { | ||
| body: JSON.stringify({ name: secretName, value: secretValue }), | ||
| contentType: 'application/json', | ||
| }); | ||
|
|
||
| test('POST request with JSON body - create blueprint', async () => { | ||
| const blueprintName = uniqueName('gateway-test-blueprint'); | ||
| expect(createResult.httpCode).toBe(200); | ||
| const created = JSON.parse(createResult.responseBody); | ||
| expect(created.name).toBe(secretName); |
There was a problem hiding this comment.
Suggestion: This test creates a secret through the gateway but never deletes it, which leaks resources across repeated smoke-test runs and can eventually hit account limits. Add cleanup in a finally block so the secret is deleted even after assertions. [resource leak]
Severity Level: Major ⚠️
- ⚠️ Smoketest suite leaks secrets in the connected Runloop account.
- ⚠️ Repeated runs can hit per-account secret quotas/limits.
- ⚠️ Additional manual cleanup needed in long-lived test environments.| const secretValue = 'test-value-from-gateway'; | |
| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| expect(created.name).toBe(secretName); | |
| const createResult = await curlRequest('POST', '/v1/secrets', { | |
| body: JSON.stringify({ name: secretName, value: secretValue }), | |
| contentType: 'application/json', | |
| }); | |
| test('POST request with JSON body - create blueprint', async () => { | |
| const blueprintName = uniqueName('gateway-test-blueprint'); | |
| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| expect(created.name).toBe(secretName); | |
| const secretValue = 'test-value-from-gateway'); | |
| try { | |
| const createResult = await curlRequest('POST', '/v1/secrets', { | |
| body: JSON.stringify({ name: secretName, value: secretValue }), | |
| contentType: 'application/json', | |
| }); | |
| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| expect(created.name).toBe(secretName); | |
| } finally { | |
| await curlRequest('DELETE', `/v1/secrets/${encodeURIComponent(secretName)}`).catch(() => {}); | |
| } |
Steps of Reproduction ✅
1. Enable smoketests by setting `RUN_SMOKETESTS=1` so the `comprehensive gateway proxying
tests` suite at `tests/smoketests/object-oriented/gateway-config.test.ts:282` runs.
2. Ensure `RUNLOOP_API_KEY` and (optionally) `RUNLOOP_BASE_URL` are set so the `beforeAll`
in that suite (`lines 331–377`) successfully provisions a gateway config, devbox, and base
secret `testSecretName`.
3. Run the Jest test file `tests/smoketests/object-oriented/gateway-config.test.ts`,
letting the test `POST request - create a secret` at lines 421–433 execute; it calls
`curlRequest` (defined at 291–329) to POST `/v1/secrets` with a unique `secretName`.
4. Observe that after the test assertions on `createResult.httpCode` and `created.name`,
there is no corresponding delete via `sdk.secret.delete` or gateway DELETE request for
`secretName`; repeated smoketest runs will accumulate secrets, unlike the `testSecretName`
created in `beforeAll` (331–347) which is explicitly deleted in `afterAll` at 391–395.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** tests/smoketests/object-oriented/gateway-config.test.ts
**Line:** 423:432
**Comment:**
*Resource Leak: This test creates a secret through the gateway but never deletes it, which leaks resources across repeated smoke-test runs and can eventually hit account limits. Add cleanup in a `finally` block so the secret is deleted even after assertions.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
|
||
| expect(createResult.httpCode).toBe(200); | ||
| const created = JSON.parse(createResult.responseBody); | ||
| expect(created.name).toBe(blueprintName); | ||
| const createResult = await curlRequest('POST', '/v1/blueprints', { | ||
| body: JSON.stringify({ | ||
| name: blueprintName, | ||
| system_setup_commands: ['echo "test"'], | ||
| }), | ||
| contentType: 'application/json', | ||
| }); | ||
|
|
||
| test('GET request with query parameters', async () => { | ||
| const { httpCode, responseBody } = await curlRequest( | ||
| 'GET', | ||
| '/v1/devboxes?limit=2&status=running', | ||
| ); | ||
| expect(createResult.httpCode).toBe(200); | ||
| const created = JSON.parse(createResult.responseBody); | ||
| expect(created.name).toBe(blueprintName); |
There was a problem hiding this comment.
Suggestion: This test creates a blueprint but does not delete it afterward, leaving orphaned blueprints in the account and causing quota/resource buildup over time. Track the created id and delete it in a finally block. [resource leak]
Severity Level: Major ⚠️
- ⚠️ Smoketest runs accumulate unused blueprints in the Runloop account.
- ⚠️ May exhaust blueprint quotas or clutter admin dashboards.
- ⚠️ Increases need for manual cleanup of test artifacts.| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| expect(created.name).toBe(blueprintName); | |
| const createResult = await curlRequest('POST', '/v1/blueprints', { | |
| body: JSON.stringify({ | |
| name: blueprintName, | |
| system_setup_commands: ['echo "test"'], | |
| }), | |
| contentType: 'application/json', | |
| }); | |
| test('GET request with query parameters', async () => { | |
| const { httpCode, responseBody } = await curlRequest( | |
| 'GET', | |
| '/v1/devboxes?limit=2&status=running', | |
| ); | |
| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| expect(created.name).toBe(blueprintName); | |
| let blueprintId: string | undefined; | |
| try { | |
| const createResult = await curlRequest('POST', '/v1/blueprints', { | |
| body: JSON.stringify({ | |
| name: blueprintName, | |
| system_setup_commands: ['echo "test"'], | |
| }), | |
| contentType: 'application/json', | |
| }); | |
| expect(createResult.httpCode).toBe(200); | |
| const created = JSON.parse(createResult.responseBody); | |
| blueprintId = created.id; | |
| expect(created.name).toBe(blueprintName); | |
| } finally { | |
| if (blueprintId) { | |
| await curlRequest('DELETE', `/v1/blueprints/${encodeURIComponent(blueprintId)}`).catch(() => {}); | |
| } | |
| } |
Steps of Reproduction ✅
1. Enable smoketests with `RUN_SMOKETESTS=1` so the `comprehensive gateway proxying tests`
suite at `tests/smoketests/object-oriented/gateway-config.test.ts:282` is active.
2. Run the Jest suite so `beforeAll` (lines 331–377) provisions the gateway/devbox and
`curlRequest` helper (291–329) is available for HTTP calls through the gateway.
3. Let the test `POST request with JSON body - create blueprint` at lines 435–449 execute;
it sends a POST to `/v1/blueprints` via `curlRequest`, receives a 200 response, parses
`created`, and asserts `created.name` matches `blueprintName`.
4. Note that unlike other tests that explicitly clean created resources (e.g., the secret
in `special characters in URL path and query params` at 597–607), this blueprint test has
no corresponding DELETE call or `sdk` cleanup; each smoketest run leaves another blueprint
in the remote account.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** tests/smoketests/object-oriented/gateway-config.test.ts
**Line:** 437:448
**Comment:**
*Resource Leak: This test creates a blueprint but does not delete it afterward, leaving orphaned blueprints in the account and causing quota/resource buildup over time. Track the created id and delete it in a `finally` block.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| const httpCode = parseInt(httpCodeLine.replace('HTTP_CODE:', ''), 10); | ||
|
|
||
| expect(httpCode).toBeGreaterThanOrEqual(400); | ||
| }); |
There was a problem hiding this comment.
Suggestion: The unauthorized-request test currently passes on any 4xx/5xx status, so server errors can be misclassified as successful auth behavior. Restrict this assertion to client-auth failure codes only. [logic error]
Severity Level: Major ⚠️
- ⚠️ Auth regression returning 5xx could pass smoketests unnoticed.
- ⚠️ Reduces reliability of unauthorized-access behavior coverage.| }); | |
| expect(httpCode).toBeLessThan(500); |
Steps of Reproduction ✅
1. Enable smoketests with `RUN_SMOKETESTS=1` so `comprehensive gateway proxying tests` at
`tests/smoketests/object-oriented/gateway-config.test.ts:282` is executed.
2. Run the Jest file so the `unauthorized request without token fails` test at lines
492–502 runs; it calls `devbox!.cmd.exec` with a `curl` command that omits the
`Authorization` header against `${gatewayUrl}/v1/devboxes?limit=1`.
3. The test parses the HTTP status code from the `curl` output (lines 496–499) and
currently asserts only `expect(httpCode).toBeGreaterThanOrEqual(400);` at 501.
4. If the gateway or backend mistakenly responds with a 5xx (e.g., 500) instead of a
client-auth error (4xx), this test will still pass, treating the server error as
acceptable unauthorized behavior; by contrast, the nearby `invalid JSON body returns
error` test at 482–490 explicitly constrains to 4xx using both `>=400` and `<500`, showing
that the narrower assertion is the intended pattern.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** tests/smoketests/object-oriented/gateway-config.test.ts
**Line:** 502:502
**Comment:**
*Logic Error: The unauthorized-request test currently passes on any 4xx/5xx status, so server errors can be misclassified as successful auth behavior. Restrict this assertion to client-auth failure codes only.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished reviewing your PR. |
✅ Object Smoke Tests & Coverage ReportTest Results✅ All smoke tests passed Coverage Results
Coverage Requirement: 100% function coverage (all public methods must be called in smoke tests) ✅ All tests passed and all object methods are covered! View detailed coverage report
|
|
This looks ok but there's a lot of extra surface area to this PR that's making it hard to read. |
7e9e5a1 to
ac132c3
Compare
User description
Format:
feat[optional scope]: <description>Examples:
feat: add new SDK method·feat(storage): support file uploads·feat!: breaking API changeDescription
AxonOps.list()to acceptAxonListParams(id, name, limit, starting_after, include_total_count) and auto-paginate viafor awaittests/sdk/axon-ops.test.tswith async-iterable mocks and new filter/options testsMotivation
Changes
src/sdk.ts— importAxonListParams, updateAxonOps.list()signature and bodytests/sdk/axon-ops.test.ts— rewrite list mocks for for await, add filter params testTesting
Breaking Changes
Checklist
feat:orfeat(scope):)CodeAnt-AI Description
Add filterable Axon listing with automatic pagination
What Changed
Impact
✅ Filtered axon lists✅ Fewer missed axons in large accounts✅ More reliable SDK list results💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.